package ws.performancetest.tests.synchronization.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Implementation of the shared memory using {@link ReentrantLock}.
 *
 * @author Wilson Santos, 36228 <wilson.santos@ua.pt>
 */
public class RLockImpl extends AbstractSharedListImpl {

  private final ReentrantLock lock = new ReentrantLock();

  public void add() throws InterruptedException {
    assert invariant();

    /* If there's no space, wait. */
    while (true) {
      lock.lock();
      if (list < MAX_SIZE) {
        break;
      } else {
        lock.unlock();
        Thread.yield();
      }
    }
    /* Add one element. */
    this.list++;
    lock.unlock();

    assert invariant();
  }

  public void remove() throws InterruptedException {
    assert invariant();

    /* If there's no elements, wait. */
    while (true) {
      lock.lock();
      if (list > 0) {
        break;
      } else {
        lock.unlock();
        Thread.yield();
      }
    }
    /* Remove one element. */
    this.list--;
    lock.unlock();

    assert invariant();
  }

  public void read() throws InterruptedException {
    lock.lock();
    try {
    } finally {
      lock.unlock();
    }
  }

  public void write() throws InterruptedException {
    lock.lock();
    try {
    } finally {
      lock.unlock();
    }
  }
}
